Syntax10.Scn.Fnt FoldElems Syntax10.Scn.Fnt (*----------------------------------------------------------------------- Make topologically sorts a set of Oberon source file names according to their import relationships so that they are in a correct compilation order. The generated list can be prepended with the command Compiler.Compile and can be compiled. Make.Order {filename} ~ reads a list of file names describing Oberon modules. The import relationships of these modules are inspected and the modules are sorted accordingly. The sorted list of file names is written to the standard output. -----------------------------------------------------------------------*) Syntax10i.Scn.Fnt StampElems Alloc 8 May 95 Syntax10b.Scn.Fnt Documentation MODULE Make; (*HM 94-06-22 / IMPORT Texts, In, Out; ModuleName = ARRAY 32 OF CHAR; Import = POINTER TO ImportDesc; Module = POINTER TO ModuleDesc; ModuleDesc = RECORD name: ModuleName; imports: Import; ref: INTEGER; next: Module END; ImportDesc = RECORD mod: Module; next: Import; END; PROCEDURE Append (VAR name: ModuleName; ext: ARRAY OF CHAR); VAR i, j: INTEGER; BEGIN i := 0; WHILE name[i] # 0X DO INC(i) END; j := 0; WHILE ext[j] # 0X DO name[i] := ext[j]; INC(i); INC(j) END; name[i] := 0X END Append; PROCEDURE ReadModuleList (VAR list: Module); VAR m: Module; BEGIN In.Open; list := NIL; WHILE In.Next() = In.name DO NEW(m); In.Name(m.name); m.imports := NIL; m.ref := 0; m.next := list; list := m END; END ReadModuleList; PROCEDURE Find (list: Module; name: ModuleName; VAR m: Module); BEGIN m := list; WHILE (m # NIL) & (m.name # name) DO m := m.next END END Find; PROCEDURE FindTop (list: Module; VAR m, prev: Module); BEGIN m := list; prev := NIL; WHILE (m # NIL) & (m.ref # 0) DO prev := m; m := m.next END END FindTop; PROCEDURE FindImports (m, list: Module); VAR t: Texts.Text; s: Texts.Scanner; p: Module; imp: Import; name: ModuleName; BEGIN NEW(t); Texts.Open(t, m.name); IF t.len > 0 THEN Texts.OpenScanner(s, t, 0); REPEAT Texts.Scan(s) UNTIL s.eot OR (s.class = Texts.Name) & (s.s = "IMPORT"); IF ~ s.eot THEN REPEAT Texts.Scan(s); IF s.class = Texts.Name THEN COPY(s.s, name); Texts.Scan(s); IF (s.class = Texts.Char) & (s.c = ":") THEN Texts.Scan(s); Texts.Scan(s); COPY(s.s, name) END; Append(name, ".Mod"); Find(list, name, p); IF p = NIL THEN NEW(p); p.name := name; p.imports := NIL; p.ref := 0 END; INC(p.ref); NEW(imp); imp.mod := p; imp.next := m.imports; m.imports := imp END UNTIL (s.class = Texts.Char) & (s.c = ";") END END FindImports; PROCEDURE Print (VAR list: Module); VAR m, prev: Module; imp: Import; BEGIN IF list # NIL THEN FindTop(list, m, prev); IF prev = NIL THEN list := m.next ELSE prev.next := m.next END; imp := m.imports; WHILE imp # NIL DO DEC(imp.mod.ref); imp := imp.next END; Print(list); Out.String(m.name); Out.Ln END Print; PROCEDURE Order*; VAR list, imports, p, m, last: Module; BEGIN ReadModuleList(list); m := list; WHILE m # NIL DO FindImports(m, list); m := m.next END; Print(list) END Order; END Make. Make.Order POPB.Mod POPC.Mod POPdump.Mod POPL.Mod POPM.Mod POPP.Mod POPS.Mod POPT.Mod POPV.Mod